package com.generalbackend.common.util;

import org.springframework.util.CollectionUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件工具类
 * @author tim.xie
 * @date 2022/6/8 11:23
 */
public class FileUtil {

    private FileUtil(){}

    /**
     * 文件复制
     * @param fromFile
     * @param toFile
     * @return
     */
    public static boolean copy(File fromFile, File toFile) {
        try (InputStream fis = new BufferedInputStream(new FileInputStream(fromFile));
             OutputStream fos = new BufferedOutputStream(new FileOutputStream(toFile))) {
            byte[] buf = new byte[2048];
            int len;
            while ((len = fis.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 创建新的文件(如果文件已存在则先删除存在的文件再创建新的文件)
     * @param fileName
     * @return
     * @throws Exception
     */
    public static boolean create(String fileName) throws Exception {
        File file = new File(fileName);
        if (file.exists()) {
            file.delete();
        }
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        return file.createNewFile();
    }

    /**
     * 获取某一目录下所有文件的文件名(不考虑还有下级目录存在)
     * @param dir
     * @return
     * @throws Exception
     */
    public static String getFileName(File dir) throws Exception {
        StringBuilder sb = new StringBuilder();
        if (!dir.exists() || !dir.isDirectory()) {
            throw new Exception("目录不存在或者不是目录");
        }
        File[] files = dir.listFiles();
        for (int i = 0; i< files.length; i++) {
            File file = files[i];
            if (file.isFile()) {
                sb.append(file.getName());
            }
            if (i < files.length) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    /**
     * 压缩文件
     * @param fileTmpPath 临时目录
     * @param tmpFiles 要压缩的临时文件列表,其中文件路径为全路径
     * @param compressName 压缩文件名称
     * @return 压缩后的文件名
     */
    public static String zipFiles(String fileTmpPath, List<String> tmpFiles, String compressName) {
        if (CollectionUtils.isEmpty(tmpFiles)) {
            return null;
        }
        // 构建压缩文件目录
        File destDir = new File(fileTmpPath + File.separator + System.currentTimeMillis() + ".zip");
        if (!destDir.exists()) {
            try {
                destDir.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        try {
            List<File> compressedFiles = new ArrayList<>();
            // 把文件复制到压缩目录
            for (String tmpFile : tmpFiles) {
                File temp = new File(tmpFile);
                if (!temp.exists()) {
                    continue;
                }
                compressedFiles.add(temp);
            }
            ZipsUtil.compress(compressedFiles, destDir);
            FileUtil.delFileList(tmpFiles);
            destDir.renameTo(new File(fileTmpPath + File.separator + compressName + ".zip"));
        } catch (Exception e) {
            FileUtil.delFileList(tmpFiles);
            e.printStackTrace();
        }
        return compressName + ".zip";
    }

    /**
     * 删除文件支持多文件一起删除
     * @param fileList
     */
    public static void delFileList(List<String> fileList) {
        for (String fileInfo : fileList) {
            File tempFile = new File(fileInfo);
            if (tempFile.exists() && tempFile.isDirectory()) {
                deleteDir(tempFile);
            } else if (tempFile.exists()) {
                tempFile.delete();
            }
        }
    }

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     * @param dir
     * @return
     */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            File[] children = dir.listFiles();
            // 递归删除目录中的子目录
            for (File aChildren : children != null ? children : new File[0]) {
                boolean success = deleteDir(aChildren);
                if (!success) {
                    return false;
                }
            }
        }
        // 目录在此时为空,可以删除
        return dir.delete();
    }

    /**
     * 向文件里写入内容
     * @param file
     * @param content
     * @return
     */
    public static boolean write(File file, String content) {
        if (!file.exists()) {
            try {
                // 创建文件
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Writer write = null;
        try {
            write = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
            write.write(content);
            write.flush();
            write.close();
        } catch (IOException e) {
            try {
                write.close();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
            e.printStackTrace();
        }
        return true;
    }


    /**
     * 向文件里写入内容
     * @param filePath
     * @param content
     * @return
     */
    public static boolean write(String filePath, String content) {
        File file = new File(filePath);
        write(file, content);
        return true;
    }

    /**
     * 读取文件内容转换为字符串
     * @param filePath
     * @return
     */
    public static String readJsonFile(String filePath) {
        String jsonStr = "";
        try {
            File jsonFile = new File(filePath);
            Reader reader = new InputStreamReader(new FileInputStream(jsonFile), "utf-8");
            int ch = 0;
            StringBuffer sb = new StringBuffer();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * 将文件内的内容以字符串的形式读取
     * @param filePath
     * @return
     */
    public static String readFileToString(String filePath) {
        FileReader fileReader = null;
        BufferedReader br = null;
        String line = null;
        StringBuilder result = new StringBuilder();
        try {
            File file = new File(filePath);
            if(!file.exists()) {
                throw new RuntimeException(file.getName() + " isn't existed");
            }
            fileReader = new FileReader(file);
            br = new BufferedReader(fileReader);
            line = br.readLine();
            while(line != null) {
                result.append(line);
                line = br.readLine();
            }
        }catch(Exception e) {
            e.toString();
        }
        finally {
            if(br != null) {
                try {
                    br.close();
                }catch(Exception e) {
                    e.toString();
                    br = null;
                }
            }
            if(fileReader != null) {
                try {
                    fileReader.close();
                }catch(Exception e) {
                    e.toString();
                }
            }
        }
        return result.toString();
    }

}
